<script setup lang="ts">
import { onMounted, ref, computed } from 'vue'
import {
  Camera,
  PerspectiveCamera,
  Scene,
  Vector3,
  WebGLRenderer,
} from 'three'
import { keyWordCode } from './typescript/enum'
import { createHelpLine, setCamera, createRenderer, createBox, createCircle } from './ts/map'
import { doSth, getCaremaPositionText, setElementSize } from './ts/active'

interface Props {
  width: number
  height: number
}

const prop = defineProps<Props>()
/** 宽高比 */
const asp = computed(() => {
  return prop.width / prop.height
})
const scene = new Scene()
let renderer: WebGLRenderer
let camera: Camera

const mapRef = ref<HTMLElement>()

onMounted(() => {
  init()
  bindEvent()
})

const bindEvent = () => {
  window.addEventListener(
    'keydown',
    (event) => {
      switch (event.keyCode) {
        case keyWordCode.Up:
          camera.position.z += 0.1
          break
        case keyWordCode.DOWN:
          camera.position.z -= 0.1
          break
        case keyWordCode.LEFT:
          camera.position.x += 0.1
          camera.position.y += 0.1
          break
        case keyWordCode.RIGHT:
          camera.position.x -= 0.1
          camera.position.y -= 0.1
          break
        case keyWordCode.SPACE:
          camera.position.setX(5)
          camera.position.setY(5)
          camera.position.setZ(5)
          camera.lookAt(0, 0, 0)
          break
        default:
          break
      }
    },
    false
  )
}

const animate = () => {
  requestAnimationFrame(animate)
  doSth()
  renderer.render(scene, camera)
}

const init = () => {
  if (mapRef.value) {
    setElementSize(mapRef.value, prop)
    initThreeElement()
    animate()
  }
}

/** 初始化 Three 元素 */
const initThreeElement = () => {
  camera = new PerspectiveCamera(75, asp.value, 0.1, 1000)
  setCamera(camera, new Vector3(5, 5, 5), new Vector3(0, 0, 0))
  renderer = createRenderer(mapRef.value as HTMLElement , prop)

  const box = createBox()
  const circle = createCircle()
  scene.add(circle)

  createHelpLine(scene)
}


const cameraInfo = computed(() => {
  return getCaremaPositionText(camera)
})
</script>

<template>
  <div ref="mapRef" class="map-wrap"></div>
  <div class="info">
    <h1>{{ cameraInfo }}</h1>
  </div>
</template>

<style scoped>
.map-wrap {
  border: 1px solid red;
}
</style>
